/**
 * 
 */
package com.sfeir.client.activity;

import static com.sfeir.client.util.Constants.BUTTON_HEIGHT;
import static com.sfeir.client.util.Constants.BUTTON_WIDTH;

import java.util.Map;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.user.client.ui.Image;
import com.google.web.bindery.event.shared.EventBus;
import com.sfeir.canvas.activities.client.AbstractCanvasActivity;
import com.sfeir.canvas.activities.client.event.PageChangeEvent;
import com.sfeir.canvas.util.client.ResourceManager;
import com.sfeir.client.GameManager;
import com.sfeir.client.i18n.TetrisConstants;
import com.sfeir.client.service.AppServiceAsync;
import com.sfeir.client.util.Constants;
import com.sfeir.shared.Level;

/**
 * @author François LAROCHE
 * 
 */
public class GamePanelActivity extends AbstractCanvasActivity {

	private static final char ROTATE_LEFT = 'a';
	private static final char ROTATE_RIGHT = 'z';
	private static final char DROP = ' ';
	private static final char DROP2 = 's';
	private static final char SPEED_UP = '+';
	private static final char SLOW_DOWN = '-';

	private static final int BACK_BUTTON_X = 15;
	private static final int BACK_BUTTON_Y = Constants.CANVAS_HEIGHT - 80;
	private static final int REFRESH_BUTTON_X = 95;
	private static final int REFRESH_BUTTON_Y = BACK_BUTTON_Y;

	private final Image back;
	private final Image background;
	private final Image refresh;

	private final GameManager manager;
	private EventBus bus;
	private final TetrisConstants texts;
	
	private Level level;
	
	private Context2d ctx;

	/**
	 * @param view
	 */
	public GamePanelActivity(ResourceManager resManager, AppServiceAsync service) {
		this.manager = new GameManager(resManager, service);
		this.back = resManager.getImage(Constants.KEY_IMAGE_BACK);
		this.background = resManager.getImage(Constants.KEY_IMAGE_BACKGROUND);
		this.refresh = resManager.getImage(Constants.KEY_IMAGE_REFRESH);
		this.texts = GWT.create(TetrisConstants.class);
	}

	@Override
	public void onClick(ClickEvent event) {
		int x = event.getX();
		int y = event.getY();
		// Click on the back button
		if (x >= BACK_BUTTON_X && x <= BACK_BUTTON_X + BUTTON_WIDTH && y >= BACK_BUTTON_Y
				&& y <= BACK_BUTTON_Y + BUTTON_HEIGHT) {
			this.bus.fireEvent(new PageChangeEvent(PageChangeEvent.BACK, null));
			return;
		}
		// Click on the refresh button
		if (x >= REFRESH_BUTTON_X && x <= REFRESH_BUTTON_X + BUTTON_WIDTH && y >= REFRESH_BUTTON_Y
				&& y <= REFRESH_BUTTON_Y + BUTTON_HEIGHT) {
			this.manager.reloadLevel(this.ctx);
			return;
		}
		if (this.manager.isGameOver()) {
			this.manager.reset(this.ctx);
			this.manager.start(this.ctx);
		}
	}

	@Override
	public void onKeyPress(KeyPressEvent event) {
		char character = event.getCharCode();
		if (ROTATE_LEFT == character) {
			manager.rotateCurrentBlockLeft(this.ctx);
			return;
		}
		if (ROTATE_RIGHT == character) {
			manager.rotateCurrentBlockRight(this.ctx);
			return;
		}
		if (SPEED_UP == character) {
			manager.speedUp();
			return;
		}
		if (SLOW_DOWN == character) {
			manager.slowDown();
			return;
		}
		if (DROP == character || DROP2 == character) {
			manager.dropPiece(this.ctx);
			return;
		}
	}

	@Override
	public void onKeyDown(KeyDownEvent event) {
		if (event.isLeftArrow()) {
			manager.moveCurrentBlockLeft(this.ctx);
			return;
		}
		if (event.isRightArrow()) {
			manager.moveCurrentBlockRight(this.ctx);
			return;
		}
		if (event.isDownArrow()) {
			manager.moveCurrentBlockDown(this.ctx);
			return;
		}
	}

	
	@Override
	public void init(Map<String, Object> context) {
		this.level = (Level) context.get(Constants.LEVEL_PARAM);
	}

	@Override
	public void start(Canvas canvas, EventBus bus) {
		this.bus = bus;
		this.ctx = canvas.getContext2d();
		// clear all
		this.ctx.drawImage(ImageElement.as(this.background.getElement()), 0, 0);
		this.ctx.drawImage(ImageElement.as(this.back.getElement()), BACK_BUTTON_X, BACK_BUTTON_Y);
		this.ctx.drawImage(ImageElement.as(this.refresh.getElement()), REFRESH_BUTTON_X, REFRESH_BUTTON_Y);
		if (null != this.level) {
			this.manager.loadLevel(this.level, this.ctx);
			initLevelArea(this.level);
		}
		this.manager.setBus(bus);
	}

	@Override
	public void stop() {
		this.manager.stop();
	}

	/**
	 * Method allowing to initialize the level number area
	 * 
	 * @param level
	 */
	private void initLevelArea(Level level) {
		this.ctx.save();
		this.ctx.setFillStyle("#ddd");
		this.ctx.setStrokeStyle("gray");
		this.ctx.setLineWidth(5);
		this.ctx.fillRect(90, 50, 150, 50);
		this.ctx.strokeRect(90, 50, 150, 50);
		this.ctx.setFillStyle("black");
		this.ctx.setFont("bolder 30px calibri");
		this.ctx.fillText(texts.level() + " " + level.getOrder(), 110, 85);
		this.ctx.restore();
	}

}
